#pragma once
#include "MyTime.h"
#define TH_ON           0
#define TH_OFF          1
#define TH_ERROR        2
#define TH_PAUSED       3
#define TH_NOMARKET     4
#define TH_PROCESSING   5
#define	TH_EXIT			6

// log message types
#define IDM_INFO		1
#define IDM_WARNING		2
#define IDM_ERROR		3
#define IDM_ALERT		4
#define IDM_ORDER       5
#define IDM_DEBUG		6
#define IDM_EVENT		7
#define IDM_RESTORE		8

// robot platforms
#define PL_COUNT		6
#define PL_PLAZA1		0
#define PL_PLAZA2		1
#define PL_ZENFIRE		2
#define PL_MICEX		3
#define PL_SELT			4
#define PL_VIRT			5

#define PLS_PLAZA1		"Plaza1"
#define PLS_PLAZA2		"Plaza2"
#define PLS_ZENFIRE		"Zen-Fire"
#define PLS_MICEX		"Micex"
#define PLS_SELT		"Selt"
#define PLS_VIRT		"Virtual"

// data message options
#define IDD_LAST_OBJECT	0x0001
#define IDD_ALLOW_SEND	0x0002
#define IDD_REMOTE_DATA	0x0010

// network options
#define MAX_NET_DATACOUNT	127
#define MAX_NET_INFOPACKET	1024
#define MAX_NET_DATAPACKET	16350
#define MAX_NET_LOGIN_SEC	10
#define MAX_NET_PASS_AGE	20
#define NET_TYPE_INFO		1
#define NET_TYPE_TICK		2
#define NET_TYPE_BIDASK		3
#define NET_TYPE_INTEREST	4
#define NET_TYPE_LOGIN		5
#define NET_TYPE_LOG		6
#define NET_TYPE_TECH		7
#define NET_TYPE_ACC		8
#define NET_DATA_HEADER		6
#define MIN_NET_PACKETSIZE	NET_DATA_HEADER+1

// min allowed value for Sleep() in ms
#define MIN_SLEEP_MS	1
#define MAX_SLEEP_MS	50400000
#define DEF_SLEEP_MS	30
#define RUN_SLEEP_MS	1
#define RUNSL_SLEEP_MS	15
#define OPER_SLEEP_MS	100
#define LOPER_SLEEP_MS	1000

// limits for parameters
#define MAX_INT			999999
#define MAX_LONG		999999999
#define MAX_DOUBLE		999999999.0
#define MAX_BYTE		255
#define MIN_PRICE		0.0001
#define MIN_PRICE_STEP  0.00001
#define MIN_VOLUME		1
#define MAX_CLIENTS		10

// max event log size
#define EVENT_LOOP_SIZE		  800
#define EVENT_LOOP_SIZE_HUGE  1500
#define EVENT_LOOP_SIZE_SMALL 400

// internal events for threads iteraction
#define WM_OnNewTickArrived			WM_USER+50
#define WM_OnNewBarArrived			WM_USER+51
#define WM_OnNewBidAskArrived 		WM_USER+52
#define WM_OnNewCommonArrived		WM_USER+53
#define WM_OnNewTrainArrived		WM_USER+54
#define WM_OnLoginReceived			WM_USER+55
#define WM_OnNewMessageReceived		WM_USER+56
#define WM_OnLogMessage				WM_USER+61
#define WM_OnSuspend				WM_USER+64
#define WM_OnResume					WM_USER+65
#define WM_OnDisconnect				WM_USER+19

class CDataReceiver;
struct SSettingsDataReceiver
{
	BOOL allow_server;

	BOOL allow_ticks;
	BOOL allow_bidask;
	BOOL allow_common;

	int  server_port;
	CString server_pass;

	BOOL write_file;
	CString file_name;

	//SSettingsDataReceiver();
};

struct SMessage
{
	BYTE Status;
	UINT Message;
	WPARAM wParam;
	LPARAM lParam;

	//SMessage();
};

// realtime bid/ask data (stakan)
struct SBidAsk
{
	int		platform;
	CMySTime time;
	int   askrows;
	int   bidrows;

	__int64 ticknum;
	__int64	index;
	int		flags;

	double  bid; 
	int   bidsize; 
	double  ask; 
	int   asksize;

	SBidAsk();
	BOOL IsCorrect();
};

// struct for ticks storage
struct STick
{
	int		platform;
	CMySTime time;
	double  price; 
	int    volume;
	char	action;
	__int64	ticknum;
	int	interest;
	int	delay;
	int		flags;

	STick();
	BOOL IsCorrect();
};

// struct for common data storage
struct SCommon
{
	int		platform;
	CMySTime time;
	int   totbidsize;
	int   totasksize;
	double limit_max;
	double limit_min;
	double session_high;
	double session_low;
	double session_close;
	int   session_volume;
	double margin_buy;
	double margin_sell;
	int   interest;
	int	   flags;

	SCommon();
	BOOL IsCorrect();
};

struct STickerInfo
{
	CString ticker_str;
	int ticker_id;
	CString market_str;
	int market_id;

	double last_price;
	double last_bid;
	double last_ask;

	int last_ask_size;
	int last_bid_size;

	__int64 last_ticknum;
	__int64 last_index;

	double max_error;

	STickerInfo();
};

// CDPSocket

class CNetSocket : public CSocket
{
	// Attributes
public:
	int Status;

	// Operations
public:
	CNetSocket();
	CNetSocket(CDataReceiver *pdatareceiver);

	~CNetSocket();

	// Overrides

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(MySocket)
public:
	void OnClose(int nErrorCode);
	void OnReceive(int nErrorCode);
	//}}AFX_VIRTUAL

	// Implementation
protected:
	CDataReceiver *pDataReceiver;
	DWORD dwReceived;
	char packet[MAX_NET_DATAPACKET];
	char *buff;
	char *ptr;
	BOOL ret;
	int data_size;
	int nRead;
	int cur_pos;
	int type;
	int i;
};


// CConnector

class CDataReceiver : public CWinThread
{
	DECLARE_DYNCREATE(CDataReceiver)

public:
	CDataReceiver();           // protected constructor used by dynamic creation
	~CDataReceiver();

	// Attributes
public:
	int Status;
	int Verbosity;
	
	SSettingsDataReceiver Settings;

	int ReceivedTicks;
	int ReceivedBidAsks;
	int ReceivedCommon;

	//SDelayStat DataDelays[PL_COUNT];

	BOOL Disconnecting;
	BOOL Connecting;
	int ActiveCount;

	HANDLE ModuleActionDone;

	int tick_size;
	int bidask_size;
	int common_size;

	BOOL InitInstance();
	int ExitInstance();
	int  Run();

	BOOL InitMessageLoop();
	void DeInitMessageLoop();
	BOOL PostThreadMessage(UINT message, WPARAM wParam, LPARAM lParam);

	void Log(LPCTSTR message, BYTE type=IDM_INFO, int code=0);

	void NetClose(CNetSocket *pSocket);

	BOOL IsRunning();

protected:
	HANDLE NewMessage;
	CRITICAL_SECTION LoopLock;
	SMessage *LastMessagePtr;
	SMessage *FirstMessagePtr;
	SMessage *CurMessagePtr;
	int MessageLoopSize;

	HANDLE hTimer;
	HANDLE hTimerQueue;

	BOOL data_pending[PL_COUNT];
	CMySTime data_time[PL_COUNT];

	char *buff;
	char *target;
	//char count;
	char *ptr;
	STick *tick;
	SBidAsk *bidask;
	SCommon *common;
	STickerInfo *ticker_info;
	int platform;
	int delay;
	int len;
	int n;
	int cur;

	CNetSocket **NetSockets;

	void OnSuspend();
	void OnResume();
	void OnConnect();
	void OnDisconnect();
	void OnNewTickArrived(char *buffer);
	void OnNewBidAskArrived(char *buffer);
	void OnNewCommonArrived(char *buffer);
	void OnNewMessageReceived(char *message, int length);

	//void CalcDelays(SDelayStat *delay_stat, int delay, int calc_avg_period, int type);

	BOOL StartTimer(int Ms);
	void StopTimer();
	void OnTimer(WPARAM nTimerID,LPARAM lParam);
	static VOID CALLBACK TimerCallback(PVOID lpParam, BOOLEAN TimerOrWaitFired);
	void ProcessMessage(int timeout_ms);
};


